package sk.ygor.raynor.rebind.serializable

import com.google.gwt.core.ext.typeinfo.JType
import sk.ygor.raynor.client.reflection.JSONTypeInfo
import sk.ygor.raynor.client.json.basetype._

object BaseTypeAnalysis extends TypeAnalysis {
  val CORE_TYPES = Map(
    classOf[java.lang.String].getName -> (JSONTypeInfo.BaseType.Nature.STRING, classOf[java_lang_String_JSONSerializer]),

    classOf[java.lang.Character].getName -> (JSONTypeInfo.BaseType.Nature.CHARACTER, classOf[java_lang_Character_JSONSerializer]),
    classOf[char].getName -> (JSONTypeInfo.BaseType.Nature.CHARACTER, classOf[java_lang_Character_JSONSerializer]),

    classOf[java.lang.Integer].getName -> (JSONTypeInfo.BaseType.Nature.INTEGER, classOf[java_lang_Integer_JSONSerializer]),
    classOf[int].getName -> (JSONTypeInfo.BaseType.Nature.INTEGER, classOf[java_lang_Integer_JSONSerializer]),

    classOf[java.lang.Long].getName -> (JSONTypeInfo.BaseType.Nature.LONG, classOf[java_lang_Long_JSONSerializer]),
    classOf[long].getName -> (JSONTypeInfo.BaseType.Nature.LONG, classOf[java_lang_Long_JSONSerializer]),

    classOf[java.lang.Short].getName -> (JSONTypeInfo.BaseType.Nature.SHORT, classOf[java_lang_Short_JSONSerializer]),
    classOf[short].getName -> (JSONTypeInfo.BaseType.Nature.SHORT, classOf[java_lang_Short_JSONSerializer]),

    classOf[java.lang.Byte].getName -> (JSONTypeInfo.BaseType.Nature.BYTE, classOf[java_lang_Byte_JSONSerializer]),
    classOf[byte].getName -> (JSONTypeInfo.BaseType.Nature.BYTE, classOf[java_lang_Byte_JSONSerializer]),

    classOf[java.lang.Float].getName -> (JSONTypeInfo.BaseType.Nature.FLOAT, classOf[java_lang_Float_JSONSerializer]),
    classOf[float].getName -> (JSONTypeInfo.BaseType.Nature.FLOAT, classOf[java_lang_Float_JSONSerializer]),

    classOf[java.lang.Double].getName -> (JSONTypeInfo.BaseType.Nature.DOUBLE, classOf[java_lang_Double_JSONSerializer]),
    classOf[double].getName -> (JSONTypeInfo.BaseType.Nature.DOUBLE, classOf[java_lang_Double_JSONSerializer]),

    classOf[java.lang.Boolean].getName -> (JSONTypeInfo.BaseType.Nature.BOOLEAN, classOf[java_lang_Boolean_JSONSerializer]),
    classOf[boolean].getName -> (JSONTypeInfo.BaseType.Nature.BOOLEAN, classOf[java_lang_Boolean_JSONSerializer])
    )

  def runAnalysis(serializableType: JType): AnalysisResult =
    CORE_TYPES.get(serializableType.getQualifiedSourceName()) match {
      case Some((nature, c)) => Analyzed(
        BaseTypeStructureInfo(
          nature,
          ClassInfo(c.getPackage.getName, c.getSimpleName)
          )
        )
      case None => Rejected("not a base type")
    }
}

case class BaseTypeStructureInfo(nature: JSONTypeInfo.BaseType.Nature, serializerClass: ClassInfo) extends StructureInfo {
  def serializer = serializerClass

  def dependendTypes = Nil
}
